package com.hzyl.famousreader.viewmodel;

import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.ViewModel;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.blankj.utilcode.util.ThreadUtils;
import com.blankj.utilcode.util.ToastUtils;
import com.hzyl.famousreader.repository.cache.ClassificationCache;
import com.hzyl.famousreader.repository.cache.ShopCache;
import com.hzyl.famousreader.repository.persistence.AppDataBase;
import com.hzyl.famousreader.repository.persistence.dao.BookDao;
import com.hzyl.famousreader.repository.persistence.entity.Book;
import com.hzyl.famousreader.repository.persistence.entity.BookChapter;
import com.hzyl.famousreader.repository.webservice.RetrofitClient;
import com.hzyl.famousreader.repository.webservice.api.BookService;
import com.hzyl.famousreader.repository.webservice.cache.ApiResponse;
import com.hzyl.famousreader.repository.webservice.cache.NetworkBoundResource;
import com.hzyl.famousreader.repository.webservice.cache.Resource;
import com.hzyl.famousreader.repository.webservice.model.BookWrapper;
import com.hzyl.famousreader.repository.webservice.model.Classification;
import com.hzyl.famousreader.repository.webservice.model.Result;

import java.util.Date;
import java.util.List;

/**
 * 书籍
 */
public class BookViewModel extends ViewModel {

  private BookDao bookDao;

  private BookService bookService;

  private ShopCache shopCache;

  private ClassificationCache classificationCache;

  public BookViewModel() {
    bookDao = AppDataBase.getInstance().bookDao();
    bookService = RetrofitClient.getInstance().create(BookService.class);
    shopCache = new ShopCache();
    classificationCache = new ClassificationCache();
    //classificationBooks = new MutableLiveData<>();
  }

  /**
   * 书架列表
   *
   * @return
   */
  public LiveData<List<Book>> bookshelves() {
    return bookDao.selectBooks();
  }

  /**
   * 推荐书籍榜单
   *
   * @return
   */
  public LiveData<Resource<List<BookWrapper>>> recommendBooks() {
    return shopCache.getAsLiveData();
  }

  /**
   * 书籍是否已经添加到书架
   *
   * @param id
   * @return
   */
  public LiveData<Integer> isAddToBookshelf(Long id) {
    return bookDao.selectCount(id);
  }

  /**
   * 添加书籍到书架
   *
   * @param book
   */
  public void addBookToBookshelf(Book book) {
    ThreadUtils.executeByIo(new ThreadUtils.SimpleTask<Long>() {
      @Nullable
      @Override
      public Long doInBackground() throws Throwable {
        return bookDao.insert(book);
      }

      @Override
      public void onSuccess(@Nullable Long result) {
        if (result != null && result > 0) {
          ToastUtils.showShort("添加书籍至书架");
        } else {
          ToastUtils.showShort("添加书籍失败");
        }
      }
    });
  }

  /**
   * 从书架移除书籍
   *
   * @param id
   */
  public void deleteBook(Long id) {
    ThreadUtils.executeByIo(new ThreadUtils.SimpleTask<Integer>() {
      @Nullable
      @Override
      public Integer doInBackground() throws Throwable {
        return bookDao.deleteById(id);
      }

      @Override
      public void onSuccess(@Nullable Integer result) {
        if (result != null && result > 0) {
          ToastUtils.showShort("移除书籍成功");
        } else {
          ToastUtils.showShort("移除书籍失败");
        }
      }
    });
  }

  /**
   * 设置书籍的最后阅读时间
   * @param id
   */
  public void updateLastReadDate(Long id) {
    ThreadUtils.executeByIo(new ThreadUtils.SimpleTask<Integer>() {
      @Nullable
      @Override
      public Integer doInBackground() throws Throwable {
        return bookDao.updateLastReadDate(id, new Date());
      }

      @Override
      public void onSuccess(@Nullable Integer result) {

      }
    });
  }

  /**
   * 获取书籍分类
   * @return
   */
  public LiveData<Resource<List<Classification>>> getBookClassification() {
    return classificationCache.getAsLiveData();
  }

  /**
   * 更新书籍的历史查看记录
   * @param book
   */
  public void updateBookChapterAndPage(Book book) {
    ThreadUtils.executeByIo(new ThreadUtils.SimpleTask<Integer>() {
      @Nullable
      @Override
      public Integer doInBackground() throws Throwable {
        return bookDao.updateChapterAndPage(book);
      }

      @Override
      public void onSuccess(@Nullable Integer result) {
        //LogUtils.d("更新的影响数目：", result);
      }
    });
  }

  /**
   * 根据书籍ID查找章节列表
   * @param id
   * @return
   */
  public LiveData<Resource<List<BookChapter>>> loadChaptersByBookId(Long id) {
    return new NetworkBoundResource<List<BookChapter>, Result<List<BookChapter>>>() {
      @Override
      protected void saveCallResult(@NonNull Result<List<BookChapter>> item) {
        List<BookChapter> list = item.getData();
        if(list != null && list.size() > 0) {
          bookDao.saveChapter(list);
        }
      }

      @Override
      protected boolean shouldFetch(@Nullable List<BookChapter> data) {
        return true;
      }

      @NonNull
      @Override
      protected LiveData<List<BookChapter>> loadFromDb() {
        return bookDao.selectChaptersByBookId(id);
      }

      @NonNull
      @Override
      protected LiveData<ApiResponse<Result<List<BookChapter>>>> createCall() {
        return bookService.getChapters(id);
      }
    }.getAsLiveData();
  }
}
